<!-- DEPRECATED, plase use @datawrapper/controls instead -->
<div class="color-picker-cont">
    <BaseDropdown ref:dropdown>
        <span slot="button">
            <slot>
                <div class="base-color-picker color-picker">
                    <div style="background: {validColor} none repeat scroll 0% 0%;" class="the-color">
                        <div class="transparency" style="opacity: {1-alpha(validColor)}"></div>
                    </div>
                    <span class="caret"></span>
                </div>
            </slot>
        </span>
        <span slot="content">
            {#if color}
            <div class="color-selector" on:click="event.stopPropagation()">
                <div class="palette">
                    {#each palette as c}
                    <div
                        class="color"
                        on:click="setColor(c, false)"
                        on:dblclick="setColor(c, true)"
                        data-color="{c}"
                        style="background: {c}; border-color: {borderColor(c)}"
                    >
                        <div class="transparency" style="opacity: {1-alpha(c)}"></div>
                    </div>
                    {/each}
                </div>

                <div class="color-axis lightness">
                    {#each gradient_l as c}
                    <div class="color {c == nearest_l?'selected':''}" on:click="setColor(c, false)" data-color="{c}" style="background: {c}"></div>
                    {/each}
                </div>
                <div class="color-axis saturation">
                    {#each gradient_c as c}
                    <div class="color {c == nearest_c?'selected':''}" on:click="setColor(c, false)" data-color="{c}" style="background: {c}"></div>
                    {/each}
                </div>
                <div class="color-axis hue">
                    {#each gradient_h as c}
                    <div class="color {c == nearest_h?'selected':''}" on:click="setColor(c, false)" data-color="{c}" style="background: {c}"></div>
                    {/each}
                </div>

                <div class="footer">
                    <input type="text" style="background: {color}; border-color: {borderColor}; color: {textColor}" bind:value="color" class="hex" />
                    <button class="btn btn-small ok" on:click="setColor(color, true)">
                        <i class="icon-ok"></i>
                    </button>
                    <div class="color selected" style="background: {color}">
                        <div class="transparency" style="opacity: {1-alpha(color)}"></div>
                    </div>
                </div>
            </div>
            {/if}
        </span>
    </BaseDropdown>
</div>
<script>
    import chroma from 'chroma';
    import _isUndefined from 'underscore-es/isUndefined';
    import _uniq from 'underscore-es/uniq';

    import BaseDropdown from './BaseDropdown.html';

    export default {
        components: { BaseDropdown },
        data() {
            return {
                palette: [],
                prepend: [],
                append: [],
                color: '#63c0de'
            };
        },
        computed: {
            palette({ $themeData, prepend, append }) {
                return _uniq(prepend.concat($themeData.colors.palette).concat(append));
            },
            validColor({ color }) {
                try {
                    return chroma(color).hex();
                } catch (e) {
                    return '#000000';
                }
            },
            gradient_l({ color }) {
                const lch = chroma(color).lch();
                const sample = spread(70, 55, 7, 6).map(l => chroma.lch(l, lch[1], lch[2]).hex());
                return chroma
                    .scale(['#000000'].concat(sample).concat('#ffffff'))
                    .mode('lch')
                    .gamma(0.8)
                    .padding(0.1)
                    .colors(14);
            },
            gradient_c({ color, palette }) {
                let high = chroma(color).set('lch.c', 120);
                if (isNaN(high.get('lch.h'))) {
                    high = chroma.lch(high.get('lch.l'), 50, chroma(palette[0] || '#d00').get('lch.h'));
                }
                const low = chroma(color).set('lch.c', 3);
                return chroma
                    .scale([low, high])
                    .mode('lch')
                    .gamma(1.2)
                    .colors(14);
            },
            gradient_h({ color }) {
                const lch = chroma(color).lch();
                const sample = spread(lch[2], 75, 7, 6).map(h => chroma.lch(lch[0], lch[1], h).hex());
                return chroma
                    .scale(sample)
                    .mode('lch')
                    .colors(14);
            },
            nearest_l({ color, gradient_l }) {
                return findNearest(gradient_l, color);
            },
            nearest_c({ color, gradient_c }) {
                return findNearest(gradient_c, color);
            },
            nearest_h({ color, gradient_h }) {
                return findNearest(gradient_h, color);
            },
            textColor({ color }) {
                return chroma(color).get('lab.l') > 60 ? 'black' : 'white';
            },
            borderColor({ color }) {
                return chroma(color)
                    .darker()
                    .hex();
            }
        },
        helpers: {
            borderColor(c) {
                return chroma(c).hex('rgb') === '#ffffff' ? '#eeeeee' : c;
            },
            alpha(c) {
                return chroma(c).alpha();
            }
        },
        methods: {
            setColor(color, close) {
                this.set({ color });
                if (close) {
                    this.refs.dropdown.set({ visible: false });
                }
            }
        },
        onstate({ changed, current, previous }) {
            if (changed.color) {
                try {
                    const niceHex = chroma(current.color).hex();
                    // eslint-disable-next-line
                    const { visible } = this.refs.dropdown.get();
                    if (visible && niceHex !== previous.color) {
                        this.fire('change', current.validColor);
                    }
                    if (current.validColor !== current.color) {
                        setTimeout(() => {
                            this.set({ color: current.validColor });
                        }, 100);
                    }
                } catch (e) {}
            }
        }
    };

    function findNearest(colors, color) {
        let nearestIndex = -1;
        let nearestDistance = 999999;
        if (colors[0] === colors[1]) return '-';
        colors.forEach((c, i) => {
            const dist = chroma.distance(c, color, 'lab');
            if (dist < nearestDistance) {
                nearestDistance = dist;
                nearestIndex = i;
            }
        });
        return colors[nearestIndex];
    }

    function spread(center, width, num, num2, exp) {
        const r = [center];
        const s = width / num;
        let a = 0;
        num2 = _isUndefined(num2) ? num : num2;
        exp = exp || 1;
        while (num-- > 0) {
            a += s;
            r.unshift(center - a);
            if (num2-- > 0) r.push(center + a);
        }
        return r;
    }
</script>

<style lang="less">
    .color-picker-cont {
        display: inline-block;
    }
    input.hex {
        margin-bottom: 0 !important;
    }

    .color-picker {
        width: 2em;
        height: 24px;
        border: 2px solid #fff;
        border-right-color: rgb(255, 255, 255);
        border-right-style: solid;
        border-right-width: 2px;
        border-radius: 4px;
        border-right: 20px solid #fff;
        box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3) !important;
        position: relative;
        display: inline-block;
        margin-right: 10px;
        vertical-align: middle;
    }

    .color-selector {
        box-shadow: 3px 3px 3px #eee;
        border-radius: 4px;
        border: 1px solid rgba(0, 0, 0, 0.2);
        top: 31px;
    }

    .palette .color {
        box-sizing: border-box;
        border: 2px solid;
        position: relative;
        float: none;
    }

    .palette .color.no-color {
    }

    .the-color {
        width: 100%;
        height: 100%;
        border-radius: 3px;
    }

    .base-color-picker .caret {
        position: absolute;
        top: 10px;
        right: -14px;
        width: 0px;
        cursor: pointer;
        text-align: center;
    }

    .the-color,
    .palette .color,
    .footer .color {
        .transparency {
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            background-image: url(/static/img/transparent.png);
            background-size: 10px;
            opacity: 0;
        }
    }
</style>
